package com.zplh.zplh_android_yk;

import android.os.Environment;
import android.text.TextUtils;

import com.zplh.zplh_android_yk.bean.CheckPhonelimitBean;
import com.zplh.zplh_android_yk.bean.TaskBean;
import com.zplh.zplh_android_yk.bean.TaskResultBean;
import com.zplh.zplh_android_yk.bean.WxPhoneBean;
import com.zplh.zplh_android_yk.intf.CheckPhoneLimit;
import com.zplh.zplh_android_yk.intf.GetPhone;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import io.reactivex.Observable;
import zplh.com.commonlibrary.networker.FileDownLoadSubscriber;
import zplh.com.commonlibrary.networker.NetCustomSubscriber;
import zplh.com.commonlibrary.networker.NetWorker;
import zplh.com.commonlibrary.utils.CommandResult;
import zplh.com.commonlibrary.utils.EncodedUtils;
import zplh.com.commonlibrary.utils.FileUtils;
import zplh.com.commonlibrary.utils.GsonUtils;
import zplh.com.commonlibrary.utils.LogUtils;
import zplh.com.commonlibrary.utils.ScriptUtils;
import zplh.com.commonlibrary.utils.ShellUtils;
import zplh.com.commonlibrary.utils.SystemUtils;
import zplh.com.commonlibrary.utils.ToastUtils;
import zplh.com.resourcelibrary.constants.NetConstant;

import static zplh.com.resourcelibrary.constants.TaskConstant.TASK_CLEAR;
import static zplh.com.resourcelibrary.constants.TaskConstant.TASK_UPDATA;
import static zplh.com.resourcelibrary.constants.TaskConstant.TASK_WX_CONTACTS_ADD_BIG;
import static zplh.com.resourcelibrary.constants.TaskConstant.Task_WX_ADD_FRIEND;

/**
 * Created by yong hao zeng on 2018/7/7.
 */
public class TaskExecutor {


    private static boolean isApplyScript = true;//在执行准备阶段可能会发生一些无法运行的错误 所以停止运行
    public static void  applyTask(TaskBean taskBean){
        isApplyScript = true;
        killPid();
        TaskResultBean taskResultBean = new TaskResultBean();
        taskResultBean.setTaskBean(taskBean);
        if (!checkLocalTask(taskBean)) {//检查是否是本地执行任务 无需脚本执行
            //判断任务脚本版本操作
            String scriptName = formatScriptName(taskBean);
            boolean isVersion = ScriptUtils.checkScript(ScriptUtils.getScriptPackageName(scriptName), taskBean.getScriptVersion());
            if (!isVersion) {//如果版本不正确 进行下载
                File file = FileUtils.createScriptFile(scriptName);
                if (file.exists()){//如果文件存在 就不删除
                    ScriptUtils.uninstallScript(taskBean.getPackageName());
                    if (ScriptUtils.installScript(file) == -1) {
                        taskBean.setStateMsg("脚本安装失败");
                        file.delete();
                        ToastUtils.showToastError(MyApplication.getCurrentActivity(),"脚本安装失败,重新下任务,不行清除脚本,再不行联系技术");
                        TaskManager.getInstance().markErrorTask(taskBean);
                        return;
                    }
                     applyScript(taskBean);
                }else {
                    downScript(taskBean, 0);
                }
            } else {
                applyScript(taskBean);
            }
        }else {
            executorLocalTask(taskBean);
        }
    }

    private static void downScript(TaskBean taskBean,int count) {
        String scriptName = formatScriptName(taskBean);
        NetWorker.getInstance().downLoad(new FileDownLoadSubscriber(FileUtils.createScriptFile(scriptName)) {
            @Override
            public void onSuccess(File file) {
                super.onSuccess(file);

                LogUtils.d("TaskExecutor", "脚本下载成功");
                ToastUtils.showToastSuccess(MyApplication.getCurrentActivity(), "脚本下载成功");
                ScriptUtils.uninstallScript(taskBean.getPackageName());
                if (ScriptUtils.installScript(file) == -1) {
                    taskBean.setStateMsg("脚本安装失败");
                        file.delete();
                    ToastUtils.showToastError(MyApplication.getCurrentActivity(),"脚本安装失败,重新下任务,不行清除脚本,再不行联系技术");
                    TaskManager.getInstance().markErrorTask(taskBean);
                    return;


                }
                applyScript(taskBean);

            }

            @Override
            public void onFail(String msg) {
                super.onFail(msg);
                if (count < 5) {
                    ToastUtils.showToastError(MyApplication.getCurrentActivity(), "脚本下载失败"+count+"次");

                    downScript(taskBean, count + 1);
                } else{
                    taskBean.setStateMsg("脚本下载错误");
                    ToastUtils.showToastError(MyApplication.getCurrentActivity(), msg);
                TaskManager.getInstance().markErrorTask(taskBean);
            }
            }
            @Override
            public void onProgress(float current, float total) {
                super.onProgress(current, total);
            }
        }, taskBean.getAddress_url());

    }

    /**
     * 执行本地任务 不依赖脚本的任务
     * @param taskBean
     */
    private static void executorLocalTask(TaskBean taskBean) {
        switch (taskBean.getTaskId()){
            case TASK_CLEAR+"":
                TaskManager.getInstance().cleanTask();

                break;
            case TASK_UPDATA+"":

                break;

        }
    }

    private static boolean checkLocalTask(TaskBean taskBean) {
        switch (taskBean.getTaskId()){
            case TASK_CLEAR+"":
            return true;
            default:
                return false;
        }
    }

    private static void applyScript(TaskBean taskBean) {
        applyScriptReady(taskBean);
        if (isApplyScript) {
            int i = ScriptUtils.applyScript(taskBean.getPackageName(), taskBean.getMethodName(),
                    EncodedUtils.getEncodedParam(taskBean.getDataGson()));
            if (i == -1){
                if (taskBean.getState() != TaskBean.STATE_ERROR&&TextUtils.isEmpty(taskBean.getStateMsg())) {
                    taskBean.setStateMsg("无法执行脚本");
                }
                TaskManager.getInstance().markErrorTask(taskBean);
            }
        }
    }

    //执行脚本之前的一些准备工作
    private static void applyScriptReady(TaskBean taskBean) {
        //删除ykimg文件夹
        String ykimg_path = Environment.getExternalStorageDirectory().getAbsoluteFile() + "/ykimages";
        FileUtils.deleteDir(ykimg_path);
//        ShellUtils.execCommand("rm -rf " + ykimg_path, true);
        if (TextUtils.equals(Task_WX_ADD_FRIEND+"",taskBean.getTaskId() )){//添加好友 从网络获取好吗
            getPhoneReady(taskBean);
        }else if (TextUtils.equals(TASK_WX_CONTACTS_ADD_BIG+"",taskBean.getTaskId())){//添加好友 从参数获取好吗
            try {
                SystemUtils.cleanAddressList(MyApplication.context);
                String dataGson = taskBean.getDataGson();
                JSONObject jsonObject = new JSONObject(dataGson);
                JSONObject params = jsonObject.getJSONObject("params");
                JSONArray phone = params.getJSONArray("materia_phone");
                String[] phones = new String[phone.length()];
                for (int i = 0; i < phone.length(); i++) {
                    phones[i] = phone.getString(i);
                }
                writePhone(phones,TextUtils.equals("1",params.getString("is_eight_six")));

            } catch (Exception e) {
                e.printStackTrace();
                isApplyScript = false;
                taskBean.setStateMsg("清除联系人错误");
                TaskManager.getInstance().markErrorTask(taskBean);
                return;
            }
        }
    }

    private static void killPid() {
        CommandResult result = ShellUtils.execCommand("ps |grep '.test'", true);
        if (TextUtils.isEmpty(result.successMsg)){
            return;
        }

        String msg = result.successMsg;
        int com = msg.indexOf("com");

        if (com == -1) return;
        String packageName = msg.substring(com, msg.length() );

        ShellUtils.execCommand("am force-stop " + packageName, true);

    }

    private static void getPhoneReady(TaskBean taskBean) {
        try {
            SystemUtils.cleanAddressList(MyApplication.context);
        } catch (Exception e) {
            e.printStackTrace();
            isApplyScript = false;
            taskBean.setStateMsg("清除联系人错误");
            TaskManager.getInstance().markErrorTask(taskBean);
            return;
        }


        String dataGson = taskBean.getDataGson();
        int add_nums = 5;
        String acctype ;
        String uid ;
        JSONArray reissues = null;
        try {
            boolean isAdd86 = false;
            JSONObject jsonObject = new JSONObject(dataGson);
            acctype = jsonObject.getString("accType");
            uid = jsonObject.getString("uid");
            JSONObject params = jsonObject.getJSONObject("params");
            if (!params.isNull("reissue")) {
                reissues = params.getJSONArray("reissue");
            }
            String one_add_num_s = params.getString("one_add_num_s");
            String one_add_num_e = params.getString("one_add_num_e");
            if (TextUtils.equals("1",params.getString("is_eight_six"))){
                isAdd86 = true;
            }
            if (!TextUtils.isEmpty(one_add_num_s) &&! TextUtils.isEmpty(one_add_num_e)) {
                int max = Integer.parseInt(one_add_num_e);
                int min = Integer.parseInt(one_add_num_s);
                Random random = new Random();
                add_nums = random.nextInt(max) % (max - min + 1) + min;
                LogUtils.d("执行","通讯录添加好友的次数为" + add_nums);
            }


            if (reissues != null&&reissues.length()>0){//查找addnumber
                for (int i = 0; i < reissues.length(); i++) {
                    JSONObject reissue = reissues.getJSONObject(i);
                    String name = reissue.getString("a");
                    if (TextUtils.equals(name, uid+"_"+acctype)){
                        String b = reissue.getString("b");
                        if (Integer.valueOf(b)<add_nums){
                            add_nums = Integer.valueOf(b);
                            break;
                        }
                    }
                }
            }

            boolean finalIsAdd8 = isAdd86;

            //加电话号码的回调
            NetCustomSubscriber<WxPhoneBean> subscriber = new NetCustomSubscriber<WxPhoneBean>() {

                @Override
                public void onNext(WxPhoneBean o) {
                    List<WxPhoneBean.DataBean> data = o.getData();
                    if (data == null||data.size()<1){
                        onError(new Exception("没数据了"));
                        return;
                    }
                    try {
                        jsonObject.put("PHONES", GsonUtils.createGsonString(data ));
                        jsonObject.put("custom",o.getCustom());
                        taskBean.setDataGson(jsonObject.toString());
                        writePhone(data, finalIsAdd8);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onError(Throwable e) {
                    super.onError(e);
                    if (e.getMessage().equals("error1"))
                        taskBean.setStateMsg("没数据了");
                    else if (e.getMessage().contains("超过日限制")){
                        taskBean.setStateMsg(e.getMessage());
                    }else
                        taskBean.setStateMsg(e.getMessage());
                    TaskManager.getInstance().markErrorTask(taskBean);
                    isApplyScript = false;
                }
            };


            CheckPhoneLimit limit = NetWorker.getInstance().getRetrofit().create(CheckPhoneLimit.class);
            String netType = params.getString("partition");
            Observable<CheckPhonelimitBean> checkImeiBeanObservable = limit.checkLimit(NetConstant.getChecklImit(netType),uid+"_"+acctype);
            int finalAdd_nums = add_nums;
            checkImeiBeanObservable.flatMap(bean -> {
                if (bean.getRet().equals("200")){

                    CheckPhonelimitBean.DataBean data = bean.getData();
                    int still = data.getStill();
                    jsonObject.put("still",still);
                    ToastUtils.showToastSuccess(MyApplication.getCurrentActivity(),"今日已加"+data.getAlready());
                    //生成随机获取数
                    HashMap<String, String> paramer = new HashMap<>();
                    paramer.put("zh",UserManager.getInstance().getMid());
                    paramer.put("limit", finalAdd_nums +"");
                    paramer.put("account",uid+"_"+acctype);
                    GetPhone getPhone = NetWorker.getInstance().getRetrofit().create(GetPhone.class);
                    return getPhone.getPhone(NetConstant.GET_PHONE, paramer);
                }else {
                    subscriber.onError(new Exception("今日加粉已超过限额,明日再来"));
                }
                return null;
            }).subscribe(subscriber);

        } catch (Exception e) {
            e.printStackTrace();
            isApplyScript = false;
            taskBean.setStateMsg("加粉参数错误"+e.getMessage());
            TaskManager.getInstance().markErrorTask(taskBean);
            return;
        }
    }


    private static void writePhone(List<WxPhoneBean.DataBean> data,boolean isAdd86) {
        for (WxPhoneBean.DataBean phone : data) {
            if (isAdd86){
                SystemUtils.addContact(phone.getName(), "+86"+phone.getPhone(),
                        MyApplication.context);
            }else {
                SystemUtils.addContact(phone.getName(), phone.getPhone(),
                        MyApplication.context);
            }
            ToastUtils.showToastSuccess(MyApplication.getCurrentActivity(), "添加一个联系人"+phone.getPhone());
        }
    }

    private static void writePhone(String[] data,boolean isAdd86) {
        for (String datum : data) {
            if (isAdd86){
                SystemUtils.addContact("高权重号", "+86"+datum,
                        MyApplication.context);
            }else {
                SystemUtils.addContact("高权重号", datum,
                        MyApplication.context);
            }
            ToastUtils.showToastSuccess(MyApplication.getCurrentActivity(), "添加一个联系人"+datum);
        }

    }


    public static String formatScriptName(TaskBean taskBean){
        String taskId = taskBean.getTaskId();
        int scriptVersion = taskBean.getScriptVersion();
        return taskId+"_"+scriptVersion+".apk";
    }
}
